/*------------------------------------------------------------------------------------------------------------------------------------------
--		SOURCE FILE:	Control.cpp	  -	Represents the "Data Link" Layer of the OSI model  Handles syncronization, and framing of data.
--
--		PROGRAM:		Wireless Modem Protocol Driver
--
--		FUNCTIONS:		Controlx
--						
--		DATE:			November 28th, 2011
--
--		REVISIONS:		
--
--		DESIGNER:		Mike Zobac
--
--		PROGRAMMER		Michael Wright
--
--		NOTES:			Uses a CRC implementation Copyright (c) 2000 by Michael Barr.
--------------------------------------------------------------------------------------------------------------------------------------------*/

#include "Control.h"
#include "Connect.h"
#include "Translate.h"
#include "Sync.h"
#include "Command.h"
#include "crc.h"


/*-------------------------------------------------------------------------------------------------------------------------------------------
--		FUNCTION: 		Controlx
--
--		DATE:			Nov.22 2011
--
--		DESIGNER:		Mike Zobac / Michael Wright
--
--		PROGRAMMER:		Michael Wright
--
--		INTERFACE:		void Controlx()
--
--		RETURNS:		0 When EOT is received and EOF is encountered
--
--		NOTES:			Uses a CRC implementation Copyright (c) 2000 by Michael Barr.
--------------------------------------------------------------------------------------------------------------------------------------------*/

DWORD WINAPI  Controlx(LPVOID info)
{
	int			count = 0;
	PTTYINFO	pinfo = (PTTYINFO)info;	
	DWORD		result;
	HANDLE      events[2];

	events[0] = pinfo->ENQ;
	events[1] = pinfo->FrameToSend;


	while(!pinfo->receivedLastFrame || !pinfo->endoftransmission)  //While either side has not completed sending
	{
		randomWaitTimer(pinfo);
		if(waitENQ(pinfo))  // if received an ENQ
		{
			WritePort(pinfo, (unsigned char*)"\x06"); // ACK
			while (count < MAX)
            {
                if(waitFrame(pinfo))
			    {
				    if(crcSlow(pinfo->rxFrame, FRAMESIZE))
                    {
                        WritePort(pinfo, (unsigned char*)"\x06");
						if((getData(pinfo)) == 0)  // if we haven't already received this frame
                        {	
                            pinfo->displayThread = CreateThread(NULL, 0, displayChars, pinfo, 0, &pinfo->dThread); 
                            pinfo->frameTypeExpected = ToggleType(pinfo->frameTypeExpected);
                        }
						 break;
					}
				}
                count++;
            }
            count = 0;
		}
		
		else
		{
			result = WaitForMultipleObjects(2, events, FALSE, INFINITE); // bid for the line, or wait for an ACK

			switch(result)
			{
				case WAIT_OBJECT_0:   // received an ENQ
					WritePort(pinfo, (unsigned char*)"\x06"); // ACK
					while (count < MAX)
					{
						if(waitFrame(pinfo))
						{
							if(crcSlow(pinfo->rxFrame, FRAMESIZE))
							{
								WritePort(pinfo, (unsigned char*)"\x06");
								if((getData(pinfo)) == 0)  // if we haven't already received this frame
								{	
									pinfo->displayThread = CreateThread(NULL, 0, displayChars, pinfo, 0, &pinfo->dThread); 
									pinfo->frameTypeExpected = ToggleType(pinfo->frameTypeExpected);
								}
								break;
							}
						}
						count++;
					}
					count = 0;
					break;

				case WAIT_OBJECT_0 + 1:  // can bid for the line
					WritePort(pinfo, (unsigned char*)"\x05"); // ENQ
					if(ackTimer(pinfo))             //if ENQ is ACKed
					{
						if(pinfo->frameTypeSent != pinfo->frameTypeToWrite)  // if the last frame was ACKed
						{
							packetize(pinfo);
						}
						while(count < MAX)        // Try sending the frame 3 times
						{
							WritePort(pinfo, pinfo->txFrame);
							if(!ackTimer(pinfo))	//if frame is not ACKed
							{
								count++;
							}
							else
							{
								pinfo->frameTypeSent = ToggleType(pinfo->frameTypeSent);
								delay(pinfo);
								break;
							}
						}
						count = 0;
					}
					break;
			}
		}
	}
	return 0;
}	
